#include "Rolling.h"
#include "RenderManager.h"
#include "Resources.h"
#include "GameTime.h"
#include "CollisionTypes.h"
#include "SpecialEffectManager.h"
#include "Explosion.h"

Rolling::Rolling(float direction)
{
	_ct.push_back(CT_ENEMY);
	_mf.push_back(CT_PLAYER);
	_shader.loadFromFile("gfx/frag/hit.frag", sf::Shader::Fragment);
	_shader.setParameter("percent", 5.0f);
	_health = 50;
	_totalHealth = _health;
	_damage = 5;
	_type = "Rolling";
	_component |= COMPONENT_COLLIDEABLE;
	_component |= COMPONENT_DRAWABLE;
	Resources::getSingletonPtr()->loadSprite(_sprite, "ROLLING_ENEMY");
	Resources::getSingletonPtr()->loadAnimations(_anim, "ROLLING_ANIM");
	_anim.setAnimation("roll");
	_direction = direction;
	_dimension = sf::Vector2f(32.0f, 32.0f);
	_position = sf::Vector2f(80.0f, 50.0f);
	_killMe = false;
	removeFlag(GHOST);
	_onGround = false;
	_mass = 1.0f;
	_canTakeDamage = true;
	_hitFlash = true;
	_interpolation = 0;
	_percent = 1.0f;
	_readyToDie = false;
}


Rolling::~Rolling(void)
{
}

void Rolling::move()
{
	_velocity.x = (_direction * 100.0f) * GameTime::getSingleton()->deltaTime();
}

void Rolling::update()
{
	if (((flags() & COLLISION_HIT_LEFT) == COLLISION_HIT_LEFT) || ((flags() & COLLISION_HIT_RIGHT) == COLLISION_HIT_RIGHT))
		_direction *= -1.0f;

	if (_readyToDie)
	{
		if (_anim.getCurrentID() == "dying")
		{
			if (_anim.isDone())
			{
				kill();
			}
		}
	}

	_anim.update();
}

void Rolling::draw(RenderManager* rm)
{
	/*sf::RectangleShape rectc(sf::Vector2f(collisionBox().width, collisionBox().height));
	rectc.setPosition(collisionBox().left, collisionBox().top);
	rm->draw(rectc);*/

	_sprite.setPosition(_position);
	sf::IntRect rect = _sprite.getTextureRect();
	rect.left = _anim.getCurrentFrame() * rect.width;
	rect.top = _anim.getCurrentRow() * rect.height;
	_sprite.setTextureRect(rect);

	if (!_hitFlash)
		rm->draw(_sprite);
	else
	{
		interpolateHitFlash();
		rm->draw(_sprite, _shader);
	}
}

void Rolling::initialize()
{

}

void Rolling::clean()
{

}

sf::FloatRect Rolling::collisionBox(int type)
{
	switch (type)
		{
		case VELOCITY_NORMAL:
			return sf::FloatRect(_position.x - (_dimension.x * 0.5f), _position.y - (_dimension.y * 0.5f), _dimension.x, _dimension.y);
		case VELOCITY_AFTER_MOVEMENT:
			return sf::FloatRect((_position.x - (_dimension.x * 0.5f)) + _velocity.x, (_position.y - (_dimension.y * 0.5f)) + _velocity.y, _dimension.x, _dimension.y);
		case VELOCITY_AFTER_MOVEMENT_X:
			return sf::FloatRect((_position.x - (_dimension.x * 0.5f)) + _velocity.x, _position.y - (_dimension.y * 0.5f), _dimension.x, _dimension.y);
		case VELOCITY_AFTER_MOVEMENT_Y:
			return sf::FloatRect(_position.x - (_dimension.x * 0.5f), (_position.y - (_dimension.y * 0.5f)) + _velocity.y, _dimension.x, _dimension.y);
		case GROUND_SENSOR:
			return sf::FloatRect(_position.x - (_dimension.x * 0.5f), _position.y + (_dimension.y * 0.5f) - 2.0f, _dimension.x, 2.0f);
		case GROUND_SENSOR_AFTER_MOVEMENT:
			return sf::FloatRect((_position.x - (_dimension.x * 0.5f)) + _velocity.x, (_position.y + (_dimension.y * 0.5f) - 2.0f) + _velocity.y, _dimension.x, 2.0f);
		case GROUND_SENSOR_AFTER_MOVEMENT_X:
			return sf::FloatRect((_position.x - (_dimension.x * 0.5f)), (_position.y + (_dimension.y * 0.5f) - 2.0f), _dimension.x, 2.0f);
		case GROUND_SENSOR_AFTER_MOVEMENT_Y:
			return sf::FloatRect((_position.x - (_dimension.x * 0.5f)) + _velocity.x, (_position.y + (_dimension.y * 0.5f) - 2.0f) + _velocity.y, _dimension.x, 2.0f);
		case LEFT_SENSOR:
			return sf::FloatRect(_position.x - (_dimension.x * 0.5f) - 2.0f, _position.y - (_dimension.y * 0.5f), 2.0f, _dimension.y);
		case RIGHT_SENSOR:
			return sf::FloatRect(_position.x + (_dimension.x * 0.5f), _position.y - (_dimension.y * 0.5f), 2.0f, _dimension.y);
		case FLOOR_SENSOR:
			return sf::FloatRect(_position.x - (_dimension.x * 0.5f), _position.y + (_dimension.y * 0.5f), _dimension.x, 4.0f);
		case FLOOR_SENSOR_AFTER_MOVEMENT:
			return sf::FloatRect((_position.x - (_dimension.x * 0.5f)) + _velocity.x, (_position.y + (_dimension.y * 0.5f)) + _velocity.y, _dimension.x, 4.0f);
		case FLOOR_SENSOR_AFTER_MOVEMENT_X:
			return sf::FloatRect((_position.x - (_dimension.x * 0.5f)) + _velocity.x, _position.y + (_dimension.y * 0.5f), _dimension.x, 4.0f);
		case FLOOR_SENSOR_AFTER_MOVEMENT_Y:
			return sf::FloatRect(_position.x - (_dimension.x * 0.5f), (_position.y + (_dimension.y * 0.5f)) + _velocity.y, _dimension.x, 4.0f);
		}
	return sf::FloatRect(0.0f, 0.0f, 0.0f, 0.0f);
}

void Rolling::takeDamage(int damage)
{
	_health -= damage;
	if (!_readyToDie)
	{
		if (static_cast<float>(_health) <= (static_cast<float>(_totalHealth) * 0.25f) )
		{
			_readyToDie = true;
			_anim.setAnimation("dying");
			_dimension.y *= 0.5f;
		}
	}
	_canTakeDamage = false;
	_hitFlash = true;
	if (_health <= 0)
		kill();
}

void Rolling::interpolateHitFlash()
{
	const float increase = 200.0f;
	if (_interpolation == 0)
	{
		_percent = std::min(_percent + (increase * GameTime::getSingleton()->deltaTime()), 10.0f);
		if (_percent == 10.0f)
			_interpolation = 1;
	}
	else if (_interpolation == 1)
	{
		_percent = std::max(_percent - (increase * GameTime::getSingleton()->deltaTime()), 1.0f);
		if (_percent == 1.0f)
		{
			_hitFlash = false;
			_canTakeDamage = true;
			_interpolation = 0;
		}
	}
	_shader.setParameter("percent", _percent);
}

void Rolling::kill()
{
	_killMe = true;
	SpecialEffectManager::getSingletonPtr()->addEffect(new Explosion(_position));
}